package com.zozo.guanli.service;

import java.io.Serializable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.zozo.guanli.dao.HibernateDao;

@Service
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public abstract class BaseService<T, PK extends Serializable> {
    protected static Logger logger = Logger.getLogger(BaseService.class);

    protected abstract HibernateDao<T, PK> getDao();

    public HttpServletRequest getRequest() {
        if (RequestContextHolder.getRequestAttributes() == null) {
            return null;
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }

    //    @Transactional(readOnly = true)
    //    public Page<T> findPage(T entity, Integer pageNo, Integer pageSize) {
    //        Page<T> page = getDao().findPaged(entity, pageNo, pageSize);
    //        return page;
    //    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void batchUpdate(List<T> entitys) {
        for (T entity : entitys) {
            update(entity);
        }
    }

    /**
     * 修改对象
     * @param entity
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void update(T entity) {
        getDao().update(entity);
    }

    /**
     * 新增一个对象
     * @param entity
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(T entity) {
        getDao().save(entity);
    }

    /**
     * 新增或修改一个对象
     * @param entity
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrUpdate(T entity) {
        getDao().saveOrUpdate(entity);
    }

    /**
     * 新增或修改一个对象
     * @param entity
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void saveOrMerge(T entity, PK id) {
        if (id != null) {
            merge(entity);
        } else {
            save(entity);
        }
    }

    /**
     * 修改一个对象
     * @param entity
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void merge(T entity) {
        getDao().merge(entity);
    }

    /**
     * 根据主键删除一个对象
     * @param id
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void delete(PK id) {
        getDao().delete(id);
    }

    /**
     * 根据主键获取一个实体对象
     * @param id
     * @return
     */
    public T get(PK id) {
        return getDao().get(id);
    }

    /**
     * 按属性查找对象列表, 匹配方式为相等.
     */
    public List<T> findBy(String propertyName, Object value) {
        return getDao().findBy(propertyName, value);
    }

    /**
     * 按属性查找唯一对象, 匹配方式为相等.
     */
    public T findUniqueBy(String propertyName, Object value) {
        return getDao().findUniqueBy(propertyName, value);
    }

    /**
     * 判断对象的属性值在数据库内是否唯一.
     * 
     * 在修改对象的情景下,如果属性新修改的值(value)等于属性原来的值(orgValue)则不作比较.
     */
    public boolean isPropertyUnique(String propertyName, Object newValue, Object oldValue) {
        return getDao().isPropertyUnique(propertyName, newValue, oldValue);
    }

}
